#pragma once

#include "znx_thread_mem.h"
#include "znx_syscall.h"

typedef struct znx_thread_base_s                znx_thread_base_t;
typedef void *(*znx_thread_base_execute_pt)(znx_thread_base_t *thread_base);


struct znx_thread_base_s {
    const char                              *tag;
    znx_thread_base_execute_pt              execute_pt;
    void                                    *data;
    znx_thread_t                            tid;
    znx_thread_mem_freelists_t              *mem_freelists;
    znx_thread_4kaligned_mem_freelists_t    *aligned_mem_freelists;
};

extern __thread size_t  g_buf_size;
extern __thread u_char  *g_buf;
extern __thread size_t  g_log_buf_size;
extern __thread u_char  *g_log_buf;
extern __thread znx_thread_base_t *current_thread_base;

void znx_g_buf_grow(size_t size);

void znx_g_log_buf_grow(size_t size);

void znx_thread_base_start(
    const char *tag,
    znx_thread_base_t *thread_base,
    znx_thread_base_execute_pt execute_pt,
    void *data,
    int64_t mem_freelists_level,
    int64_t aligned_mem_freelists_level);


void
znx_thread_base_join(znx_thread_base_t *thread_base, void **ret);


void *znx_thread_malloc(size_t size);
void znx_thread_free(void *ptr);

static inline void *
znx_thread_calloc(size_t size)
{
    void *ptr = znx_thread_malloc(size);
    bzero(ptr, size);
    return ptr;
}


void *znx_thread_aligned_malloc(size_t size);
void znx_thread_aligned_free(void *ptr);

